
let window = globalThis;
const sealedbox = require('tweetnacl-sealedbox-js');
const naclUtil = require('tweetnacl-util');

// 定义常量和变量
var h, // Promise模块缓存
    i = window.crypto, // 获取浏览器加密API
    j = 64, // 公钥长度(字节)
    k = 1,  // 版本号
    l = 1,  // 版本号字段长度
    m = 1,  // 算法标识字段长度
    n = 2,  // 加密密钥长度字段长度
    o = 32, // AES密钥长度(字节)
    p = 16, // 认证标签长度(字节)
    q = l + m + n + o + sealedbox.overheadLength + p; // 信封头部总长度

// 使用tweetnacl-sealedbox加密数据
function r(a, b) {
    return sealedbox.seal(a, b)
}

// 将16进制字符串转换为Uint8Array
function s(a) {
    var b = [];
    for (var c = 0; c < a.length; c += 2)
        b.push(parseInt(a.slice(c, c + 2), 16));
    return new Uint8Array(b)
}

// 主加密函数
function a(a, d, e, f) {
    // 计算总输出长度 = 头部长度 + 数据长度
    var g = q + e.length;

    // 验证公钥格式
    if (d.length != j)
        throw new Error("public key is not a valid hex sting");
    var t = s(d);
    if (!t)
        throw new Error("public key is not a valid hex string");

    // 准备输出缓冲区
    var u = new Uint8Array(g),
        v = 0; // 缓冲区偏移量

    // 写入版本号
    u[v] = k;
    v += l;

    // 写入算法标识
    u[v] = a;
    v += m;

    // 配置AES密钥生成参数
    d = {
        name: "AES-GCM",
        length: 256 // 256位
    };

    // 配置AES加密参数
    var w = {
        name: "AES-GCM",
        iv: new Uint8Array(12), // 初始化向量
        additionalData: f,     // 附加认证数据
        tagLen: p              // 认证标签长度
    };

    // 生成AES密钥并加密数据
    return i.subtle.generateKey(d, !0, ["encrypt", "decrypt"])
        .then(function (a) {
            // 导出密钥原始数据
            var c = i.subtle.exportKey("raw", a);
            // 加密数据
            a = i.subtle.encrypt(w, a, e.buffer);
            console.log(a);
            return Promise.all([c, a])
        })
        .then(function (a) {
            // 处理加密结果
            var b = new Uint8Array(a[0]);
            // 使用公钥加密AES密钥
            b = r(b, t);

            // 写入加密密钥长度
            u[v] = b.length & 255;
            u[v + 1] = b.length >> 8 & 255;
            v += n;

            // 写入加密后的AES密钥
            u.set(b, v);
            v += o;
            v += sealedbox.overheadLength;

            // 验证密钥长度
            if (b.length !== o + sealedbox.overheadLength)
                throw new Error("encrypted key is the wrong length");

            // 处理加密数据
            b = new Uint8Array(a[1]);
            // 分离认证标签和数据
            a = b.slice(-p); // 认证标签
            b = b.slice(0, -p); // 加密数据

            // 写入认证标签
            u.set(a, v);
            v += p;

            // 写入加密数据
            u.set(b, v);
            return u
        })
    ["catch"](function (a) {
        throw a
    })
}


let as = "180"
let bs = 'b468edf66cbd3c5a959eb78b813f31a2a1e6a571f6df7a098675773846716926'
let es = naclUtil.decodeUTF8("17620532352");
let ks = naclUtil.decodeUTF8("1744645356");


a(as, bs, es, ks).then((res) => {
    console.log(naclUtil.encodeBase64(res));

})
